package net.wicp.tams.duckula.server.connector;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.common.Conf;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.apiext.OSinfo;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.connector.beans.CusDynaBean;
import net.wicp.tams.common.connector.executor.IBusiApp;
import net.wicp.tams.common.constant.EPlatform;
import net.wicp.tams.common.exception.ExceptAll;
import net.wicp.tams.common.exception.ProjectException;
import net.wicp.tams.common.others.docker.DockerUtilSpotify;
import net.wicp.tams.common.thread.ThreadPool;
import net.wicp.tams.duckula.server.service.ServerAssit;

@Service(value = "TaskStart")
@Slf4j
public class TaskStart implements IBusiApp {

	private static final org.slf4j.Logger docker = org.slf4j.LoggerFactory.getLogger("docker");

	@Override
	public CusDynaBean exe(CusDynaBean inputBean, CusDynaBean outBeanOri) throws ProjectException{
		long begintime = System.currentTimeMillis();
		String taskId = inputBean.getStrValueByName("taskId");
		int jmxPort = Integer.parseInt(inputBean.getStrValueByName("jmxPort"));
		String debugPort = inputBean.getStrValueByName("debugPort");
		// String containerId = inputBean.getStrValueByName("containerId");
		// String imgId = inputBean.getStrValueByName("imgId");
		String enableDocker = Conf.get("duckula.docker.enable");
		if (StringUtil.isNotNull(enableDocker) && "true".equals(enableDocker)) {// 走docker
			String imageId = Conf.get("duckula.docker.imageid");
			String containerId = ServerAssit.findContainerId(taskId);
			if (StringUtil.isNotNull(containerId)) {
				try {
					DockerUtilSpotify.getInst().getDocker().startContainer(containerId);
					docker.info("{}={}", taskId, containerId);
					outBeanOri.setResult(Result.getSuc());
				} catch (Exception e) {
					log.error("启动containerId:{" + containerId + "异常", e);
					outBeanOri.setResult(Result.getError("启动containerId:" + containerId + "异常"));
				}
			} else {
				Result ret = DockerUtilSpotify.getInst().startContainer(imageId, taskId, String.valueOf(jmxPort), debugPort);
				docker.info("{}={}", taskId, ret.getMessage());
				outBeanOri.setResult(ret);
				if (!ret.isSuc()) {
					log.error("启动imgId:{}异常{}", imageId, ret.getMessage());
				}
			}
		} else {
			String homePath = System.getenv().get("DUCKULA_HOME");
			String cmdtrue = "";			
			if(OSinfo.getOSname()==EPlatform.Windows) {
				String cmd = IOUtil.mergeFolderAndFilePath(homePath, "/bin/run.bat");				
				if (StringUtil.isNull(debugPort)) {
					//call是在命令行執行
					cmdtrue = String.format("cmd /c start %s %s %s", cmd, taskId, jmxPort);
				} else {
					cmdtrue = String.format("cmd /c start %s %s %s %s", cmd, taskId, jmxPort, debugPort);
				}
			}else if(OSinfo.getOSname()==EPlatform.Linux) {
				String cmd = IOUtil.mergeFolderAndFilePath(homePath, "/bin/run.sh");				
				if (StringUtil.isNull(debugPort)) {
					cmdtrue = String.format("sh %s %s %s", cmd, taskId, jmxPort);
				} else {
					cmdtrue = String.format("sh %s %s %s %s", cmd, taskId, jmxPort, debugPort);
				}
			}else{
				outBeanOri.setResult(ExceptAll.project_nosupportos, "只支持windows和linux");
				return outBeanOri;
			}			
			log.info("start cmd:{}", cmdtrue);
			try {
				final Process ps = Runtime.getRuntime().exec(cmdtrue);
				ps.waitFor();
				// String instr = IOUtil.slurp(ps.getInputStream(),
				// Conf.getSystemEncode());//会无限等待
				Future<String> query = (Future<String>) ThreadPool.getDefaultPool().submit(new Callable<String>() {
					@Override
					public String call() throws Exception {
						String errstr = IOUtil.slurp(ps.getErrorStream(), Conf.getSystemEncode());
						return errstr;
					}
				});
				try {
					String retstr = query.get(10, TimeUnit.SECONDS);
					log.error("启动失败,原因:[{}]", retstr);
					outBeanOri.setResult(ExceptAll.project_runshell, retstr);
				} catch (ExecutionException e) {
					log.info("超时获得错误流，意味着命令没问题");
					outBeanOri.setResult(ExceptAll.no);
				} catch (TimeoutException e) {
					log.info("超时获得错误流，意味着命令没问题");
					outBeanOri.setResult(ExceptAll.no);
				}

			} catch (IOException ioe) {
				log.error("IO异常，文件有误", ioe);
				outBeanOri.setResult(Result.getError("IO异常，文件有误"));
			} catch (InterruptedException e) {
				log.error("中断异常", e);
				outBeanOri.setResult(Result.getError("中断异常"));
			}
		}
		outBeanOri.set("usetimes", String.valueOf(System.currentTimeMillis() - begintime));
		return outBeanOri;
	}
}
